package com.activiti.z_six.service.impl;

import com.activiti.z_six.SecurityUtil;
import com.activiti.z_six.entity.controllerParams.ProcessTaskParams;
import com.activiti.z_six.entity.formComponents.FormEntity;
import com.activiti.z_six.entity.orgmanagement.UserEntity;
import com.activiti.z_six.entity.taskAssignee.*;
import com.activiti.z_six.mapper.formComponentsMapper.FormEntityMapper;
import com.activiti.z_six.mapper.orgmanagementMapper.UserEntityMapper;
import com.activiti.z_six.mapper.taskAssigneeMapper.*;
import com.activiti.z_six.security.RedisUtils;
import com.activiti.z_six.service.IAssigneeUserService;
import com.activiti.z_six.service.IProcessTaskService;
import com.activiti.z_six.util.DateUtils;
import com.activiti.z_six.util.SystemConfig;
import de.odysseus.el.ExpressionFactoryImpl;
import de.odysseus.el.util.SimpleContext;
import org.activiti.api.process.model.ProcessInstance;
import org.activiti.api.process.model.builders.ProcessPayloadBuilder;
import org.activiti.api.process.runtime.ProcessRuntime;
import org.activiti.api.runtime.shared.query.Page;
import org.activiti.api.runtime.shared.query.Pageable;
import org.activiti.api.task.model.Task;
import org.activiti.api.task.model.builders.TaskPayloadBuilder;
import org.activiti.api.task.runtime.TaskRuntime;
import org.activiti.bpmn.model.*;
import org.activiti.bpmn.model.Process;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.bpmn.behavior.ParallelMultiInstanceBehavior;
import org.activiti.engine.impl.bpmn.behavior.SequentialMultiInstanceBehavior;
import org.activiti.engine.impl.el.JuelExpression;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import javax.el.ExpressionFactory;
import javax.el.ValueExpression;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class IProcessTaskServiceImpl implements IProcessTaskService {
    @Autowired
    private SecurityUtil securityUtil;
    @Autowired //流程实例服务
    private ProcessRuntime processRuntime;
    @Autowired //任务执行服务
    private TaskRuntime taskRuntime;
    @Autowired //自定义
    private OvTaskEntityMapper ovTaskEntityMapper;
    @Autowired //流程实例服务
    private OvProcessInstanceMapper ovProcessInstanceMapper;
    @Autowired
    private ApprovalTrackMapper approvalTrackMapper;
    @Autowired //任务服务
    private TaskService taskService;
    @Autowired //历史任务服务
    private HistoryService historyService;
    @Autowired //找人服务
    private IAssigneeUserService assigneeUserService;
    @Autowired //流程发布信息服务
    private RepositoryService repositoryService;
    @Autowired //流程运行实例服务
    private RuntimeService runtimeService;
    @Autowired //用户服务
    private UserEntityMapper userEntityMapper;
    @Autowired //退回信息
    private ReturnWorkMapper returnWorkMapper;
    @Autowired //退回设置
    private ReturnWayMapper returnWayMapper;
    @Autowired //移交服务
    private TaskInstEntityMapper taskInstEntityMapper;
    @Autowired
    private FlowElementAttrsMapper flowElementAttrsMapper;
    @Autowired
    private GenerWorkMapper generWorkMapper;
    @Autowired
    private SmsEntityMapper smsEntityMapper;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private FormEntityMapper formEntityMapper;

    @Override
    public HashMap<String, Object> getHisFormJson(String processKey,String taskid){
        HashMap<String, Object> hashMap=new HashMap<>();
        try{
            //没有taskid说明是开始节点
            if(SystemConfig.IsNullOrEmpty(taskid)){
                //获取当前登录用户信息
                Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
                String username=authentication.getName();
                securityUtil.logInAs(username);

                //获取流程模版信息
                OvProcessInstance ovProcessInstance=ovProcessInstanceMapper.getProcessInsLastVersion(processKey);
                BpmnModel bpmnModel = repositoryService.getBpmnModel(ovProcessInstance.getId_());
                //获取流程信息
                Process process=bpmnModel.getProcesses().get(0);
                StartEvent startEvent=(StartEvent)process.getInitialFlowElement();
                List<SequenceFlow> outgoingFlows = startEvent.getOutgoingFlows();
                //获取UserTask类型数据
                UserTask userTask = (UserTask) outgoingFlows.get(0).getTargetFlowElement();
                FlowElementAttrs flowElementAttrs=flowElementAttrsMapper.getFlowElementAttrs(userTask.getId());

                FormEntity formEntity=formEntityMapper.formEntity(flowElementAttrs.getFormMap());
                hashMap.put("mapJson",formEntity.getForm_json());
                hashMap.put("form_type",flowElementAttrs.getForm_type());
                hashMap.put("form_url",flowElementAttrs.getForm_url());
            }
            else{
                //获取任务信息
                OvTaskEntity task = ovTaskEntityMapper.ovTaskEntity(taskid);
                FlowElementAttrs flowElementAttrs=flowElementAttrsMapper.getFlowElementAttrs(task.getTask_def_key_());

                FormEntity formEntity=formEntityMapper.formEntity(flowElementAttrs.getFormMap());
                hashMap.put("mapJson",formEntity.getForm_json());
                hashMap.put("form_type",flowElementAttrs.getForm_type());
                hashMap.put("form_url",flowElementAttrs.getForm_url());
            }
            return hashMap;
        }
        catch (Exception ex){
            return hashMap;
        }
    }
    @Override
    public HashMap<String,Object> startProcess(ProcessTaskParams processTaskParams){
        //获取当前登录用户信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String username=authentication.getName();
        securityUtil.logInAs(username);

        HashMap<String,Object> sendMap=new HashMap<>();
        //关联表单业务的主键，可通过参数传递过来，也可以自动生成
        String BusinessKey=processTaskParams.getBusinessKey();
        //启动之前，进行判断
        OvProcessInstance ovProcessInstance=ovProcessInstanceMapper.getProcessInsLastVersion(processTaskParams.getProcessKey());
        BpmnModel bpmnModel = repositoryService.getBpmnModel(ovProcessInstance.getId_());
        //获取流程信息
        Process process=bpmnModel.getProcesses().get(0);
        StartEvent startEvent=(StartEvent)process.getInitialFlowElement();
        List<SequenceFlow> outgoingFlows = startEvent.getOutgoingFlows();
        if(outgoingFlows.size()>1){
            sendMap.put("msg", "发起流程失败,启动事件后面，只能有一个任务节点");
            return sendMap;
        }
        //获取用户任务
        UserTask userTask = (UserTask) outgoingFlows.get(0).getTargetFlowElement();
        //启动实例
        ProcessInstance processInstance = processRuntime.start(ProcessPayloadBuilder
                .start()
                .withProcessDefinitionKey(processTaskParams.getProcessKey())
                .withName(processTaskParams.getProcessName())
                .withVariable(userTask.getId()+"_byStarter",username)
                .withBusinessKey(BusinessKey)
                .build());

        //获取任务信息
        org.activiti.engine.task.Task task = taskService.createTaskQuery()
                .processInstanceId(processInstance.getId())
                .singleResult();

        if(processTaskParams.getVariables()==null){
            HashMap<String,Object> variables=new HashMap<>();
            variables.put(userTask.getId()+"_byStarter",username);
            processTaskParams.setVariables(variables);
        }

        //获取下一步节点信息
        HashMap<String,Object> hashMap=getNextUserInfo(processInstance.getId(),task.getId(),processTaskParams.getVariables());
        //获取任务信息
        Task runTask=taskRuntime.task(task.getId());
        this.saveForm(runTask.getProcessInstanceId(),BusinessKey);
        //如果是待领取任务，先领取
        if(runTask.getAssignee()==null) {
            taskRuntime.claim(TaskPayloadBuilder.claim().withTaskId(runTask.getId()).build());
        }
        OvTaskEntity ovTaskEntity=ovTaskEntityMapper.ovTaskEntity(task.getId());
        //执行发送
        Task taskObj= taskRuntime.complete(TaskPayloadBuilder.complete()
                .withTaskId(task.getId())
                .withVariables(hashMap)
                .build());


        processTaskParams.setProcessInstanceId(taskObj.getProcessInstanceId());
        //增加审核记录
        this.setApprovalTrack(ovTaskEntity.getTask_def_key_(),ovTaskEntity.getName_(),processTaskParams,0,"提交");
        //下一步的接收人
        String msgToUsers=redisUtils.get(taskObj.getProcessInstanceId()+ "_sms").toString();

        if(!msgToUsers.contains(",")){
            SmsEntity smsEntity=new SmsEntity();
            smsEntity.setProce_inst_id(taskObj.getProcessInstanceId());
            smsEntity.setId(UUID.randomUUID().toString());
            smsEntity.setMsgCont("流程["+processInstance.getName()+"]["+taskObj.getName()+"]步骤已完成，目前需要您进行审核");
            smsEntity.setSender(username);
            smsEntity.setState("0");
            smsEntity.setToUser(msgToUsers);
            smsEntity.setSmsType("流程审核");
            smsEntity.setRdt(DateTime.now().toString("yyyy-MM-dd hh:mm:ss"));
            smsEntity.setTitle("您有一项流程待办需要审核");
            smsEntityMapper.addSms(smsEntity);
        }
        else{
            String[] users=msgToUsers.split(",");
            for(String user:users){
                SmsEntity smsEntity=new SmsEntity();
                smsEntity.setProce_inst_id(taskObj.getProcessInstanceId());
                smsEntity.setId(UUID.randomUUID().toString());
                smsEntity.setMsgCont("流程["+processInstance.getName()+"]["+taskObj.getName()+"]步骤已完成，目前需要您进行审核");
                smsEntity.setSender(username);
                smsEntity.setState("0");
                smsEntity.setToUser(user);
                smsEntity.setSmsType("流程审核");
                smsEntity.setRdt(DateTime.now().toString("yyyy-MM-dd hh:mm:ss"));
                smsEntity.setTitle("您有一项流程待办需要审核");
                smsEntityMapper.addSms(smsEntity);
            }
        }
        sendMap.put("msg","启动成功");
        return sendMap;
    }
    /**
    发送到下一步
     */
    @Override
    public HashMap<String,Object> sendWork(ProcessTaskParams processTaskParams){
        //获取当前登录用户信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String username=authentication.getName();
        securityUtil.logInAs(username);

        HashMap<String,Object> sendMap=new HashMap<>();
        //获取任务信息
        OvTaskEntity task = ovTaskEntityMapper.ovTaskEntity(processTaskParams.getTaskId());
        ProcessInstance processInstance = processRuntime.processInstance(task.getProc_inst_id_());

        Boolean isCanSend=false;

        //判断是否是退回状态，以及退回信息
        ReturnWorkEntity returnWorkEntity=returnWorkMapper.getReturnWork(processTaskParams.getTaskId());
        if(returnWorkEntity!=null){
            if(returnWorkEntity.getReturnTo_act_id().equals(task.getTask_def_key_())){
                ReturnWayEntity returnWayEntity=returnWayMapper.getReturnWay(task.getTask_def_key_());
                //如果是一步步向下重新走一遍
                if(returnWayEntity.getRunWay().equals("none")){
                    isCanSend=true;
                }
                //如果是直接到达退回节点
                else{
                    isCanSend=false;
                    task.setId_(processTaskParams.getTaskId());
                    task.setName_(returnWorkEntity.getReturn_act_name());
                    task.setAssignee_(returnWorkEntity.getReturnUser());
                    task.setTask_def_key_(returnWorkEntity.getReturn_act_id());
                    ovTaskEntityMapper.setTaskStatus(task);
                }
            }
            else{
                isCanSend=true;
            }
        }
        else{
            isCanSend=true;
        }

        if(isCanSend) {
            //如果是待领取任务，先领取
            if (task.getAssignee_() == null) {
                taskRuntime.claim(TaskPayloadBuilder.claim().withTaskId(task.getId_()).build());
            }
            this.saveForm(task.getProc_inst_id_(),processTaskParams.getBusinessKey());
            //获取下一步任务处理人
            HashMap<String, Object> hashMap = getNextUserInfo(task.getProc_inst_id_(), task.getId_(), processTaskParams.getVariables());
            //执行发送
            Task taskObj = taskRuntime.complete(TaskPayloadBuilder.complete()
                    .withTaskId(task.getId_())
                    .withVariables(hashMap)
                    .build());

            //增加审核记录
            this.setApprovalTrack(task.getTask_def_key_(),task.getName_(),processTaskParams,1,"审核");
            //下一步的接收人
            String msgToUsers=redisUtils.get(taskObj.getProcessInstanceId()+ "_sms").toString();
            if(!SystemConfig.IsNullOrEmpty(msgToUsers)) {
                if (!msgToUsers.contains(",")) {
                    SmsEntity smsEntity = new SmsEntity();
                    smsEntity.setProce_inst_id(taskObj.getProcessInstanceId());
                    smsEntity.setId(UUID.randomUUID().toString());
                    smsEntity.setMsgCont("流程["+processInstance.getName()+"]["+taskObj.getName()+"]步骤已完成，目前需要您进行审核");
                    smsEntity.setSender(username);
                    smsEntity.setState("0");
                    smsEntity.setToUser(msgToUsers);
                    smsEntity.setSmsType("流程审核");
                    smsEntity.setRdt(DateTime.now().toString("yyyy-MM-dd hh:mm:ss"));
                    smsEntity.setTitle("您有一项流程待办需要审核");
                    smsEntityMapper.addSms(smsEntity);
                } else {
                    String[] users = msgToUsers.split(",");
                    for (String user : users) {
                        SmsEntity smsEntity = new SmsEntity();
                        smsEntity.setProce_inst_id(taskObj.getProcessInstanceId());
                        smsEntity.setId(UUID.randomUUID().toString());
                        smsEntity.setMsgCont("流程["+processInstance.getName()+"]["+taskObj.getName()+"]步骤已完成，目前需要您进行审核");
                        smsEntity.setSender(username);
                        smsEntity.setState("0");
                        smsEntity.setToUser(user);
                        smsEntity.setSmsType("流程审核");
                        smsEntity.setRdt(DateTime.now().toString("yyyy-MM-dd hh:mm:ss"));
                        smsEntity.setTitle("您有一项流程待办需要审核");
                        smsEntityMapper.addSms(smsEntity);
                    }
                }
            }
            else{
                msgToUsers=redisUtils.get(taskObj.getProcessInstanceId()+ "_end").toString();
                if(!SystemConfig.IsNullOrEmpty(msgToUsers)){
                    HistoricProcessInstance historicProcessInstance=historyService.createHistoricProcessInstanceQuery()
                            .processInstanceId(taskObj.getProcessInstanceId())
                            .singleResult();

                    SmsEntity smsEntity = new SmsEntity();
                    smsEntity.setProce_inst_id(taskObj.getProcessInstanceId());
                    smsEntity.setId(UUID.randomUUID().toString());
                    smsEntity.setMsgCont("您的["+processInstance.getName()+"]流程申请已经审核通过。");
                    smsEntity.setSender(username);
                    smsEntity.setState("0");
                    smsEntity.setToUser(historicProcessInstance.getStartUserId());
                    smsEntity.setSmsType("流程通知");
                    smsEntity.setRdt(DateTime.now().toString("yyyy-MM-dd hh:mm:ss"));
                    smsEntity.setTitle("审核结果通知");
                    smsEntityMapper.addSms(smsEntity);
                }
            }
        }
        sendMap.put("msg","发送成功");
        return sendMap;
    }

    /**
     * 驳回
     * @param processInstanceId
     * @param taskId
     * @param returnToTaskKey
     * @param returnMsg
     * @param variables 自定义参数
     * @return
     */
    @Override
    public OvTaskEntity returnWork(String processInstanceId,String taskId,String returnToTaskKey
            ,String returnMsg
            ,HashMap<String,Object> variables){
        String re_id=UUID.randomUUID().toString();
        try {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            String username = authentication.getName();

            //查询历史数据，获取节点名称
            HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstanceId)
                    .taskDefinitionKey(returnToTaskKey).singleResult();

            //获取退回节点信息
            OvTaskEntity ovTaskEntity = ovTaskEntityMapper.ovTaskEntity(taskId);
            OvTaskEntity taskEntity=ovTaskEntity;
            //获取退回设置
            ReturnWayEntity returnWayEntity=returnWayMapper.getReturnWay(ovTaskEntity.getTask_def_key_());

            //增加退回记录
            ReturnWorkEntity returnWorkEntity = new ReturnWorkEntity();
            returnWorkEntity.setId(re_id);
            returnWorkEntity.setProc_def_id(ovTaskEntity.getProc_def_id_());
            returnWorkEntity.setProc_inst_id(ovTaskEntity.getProc_inst_id_());
            returnWorkEntity.setTaskid(taskId);
            returnWorkEntity.setReturn_act_id(ovTaskEntity.getTask_def_key_());
            returnWorkEntity.setReturn_act_name(ovTaskEntity.getName_());
            returnWorkEntity.setReturnTo_act_id(returnToTaskKey);
            returnWorkEntity.setReturnTo_act_name(historicTaskInstance.getName());
            returnWorkEntity.setReturnUser(username);
            returnWorkEntity.setReturn_msg(returnMsg);//退回原因
            returnWorkEntity.setReturn_time(DateTime.now().toString("yyyy-MM-dd hh:mm:ss"));
            returnWorkEntity.setVariables(variables.toString());


            //如果退回后，需要重新走一遍，则删除，否则，不删除
            if(returnWayEntity.getRunWay().equals("none")) {
                //删除其他分支任务
                List<OvTaskEntity> taskList = ovTaskEntityMapper.ovTaskEntityByProcessInsId(processInstanceId);
                for (OvTaskEntity task : taskList) {
                    if (task.getTask_def_key_().equals(ovTaskEntity.getTask_def_key_()))
                        continue;
                    else {
                        ovTaskEntityMapper.delete(task);
                    }
                }
            }
            ovTaskEntity.setId_(taskId);
            ovTaskEntity.setName_(historicTaskInstance.getName());
            ovTaskEntity.setAssignee_(historicTaskInstance.getAssignee());
            ovTaskEntity.setExecution_task_def_key_(ovTaskEntity.getTask_def_key_());
            ovTaskEntity.setTask_def_key_(returnToTaskKey);


            //增加退回记录
            returnWorkMapper.createReturnDetailed(returnWorkEntity);
            //更新执行节点与执行人
            ovTaskEntityMapper.setTaskStatusToReturn(ovTaskEntity);
            //增加轨迹
            this.addTaskInstTrack(processInstanceId,taskEntity,"returnWork",returnMsg);

            ProcessTaskParams processTaskParams=new ProcessTaskParams();
            processTaskParams.setVariables(variables);
            processTaskParams.setTaskId(taskId);
            processTaskParams.setProcessInstanceId(processInstanceId);
            processTaskParams.setMsg(returnMsg);
            this.setApprovalTrack(ovTaskEntity.getTask_def_key_(),ovTaskEntity.getName_(),processTaskParams,2,"驳回");

            return ovTaskEntity;
        }
        catch (Exception ex){
            returnWorkMapper.deleteReturn(re_id);
            return new OvTaskEntity();
        }
    }

    /**
     * 移交
     * @param processInstanceId
     * @param taskId
     * @param Msg
     * @param toUser
     * @param variables
     * @return
     */
    @Override
    public OvTaskEntity transfer(String processInstanceId,String taskId,String Msg,
                                 String toUser,HashMap<String,Object> variables){
        try{
            OvTaskEntity task=ovTaskEntityMapper.ovTaskEntity(taskId);
            if(task.getAssignee_()==null){
                taskRuntime.claim(TaskPayloadBuilder.claim().withTaskId(taskId).build());
            }

            OvTaskEntity ovTaskEntity = task;
            ovTaskEntity.setAssignee_(toUser);
            ovTaskEntity.setClaim_time_(DateTime.now().toString("yyyy-MM-dd hh:mm:ss"));
            //更新执行人
            ovTaskEntityMapper.setTaskStatus(ovTaskEntity);
            //增加轨迹
            this.addTaskInstTrack(processInstanceId,task,"transfer",Msg);

            ProcessTaskParams processTaskParams=new ProcessTaskParams();
            processTaskParams.setVariables(variables);
            processTaskParams.setTaskId(taskId);
            processTaskParams.setProcessInstanceId(processInstanceId);
            processTaskParams.setMsg(Msg);
            this.setApprovalTrack(ovTaskEntity.getTask_def_key_(),ovTaskEntity.getName_(),processTaskParams,3,"移交");
            return ovTaskEntity;
        }catch (Exception ex){
            return new OvTaskEntity();
            //mybatis数据库回滚事物TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }

    /**
     * 加签
     * @param processInstanceId
     * @param taskId
     * @param Msg
     * @param toUser
     * @param variables
     * @return
     */
    @Override
    public OvTaskEntity countersign(String processInstanceId,String taskId,String Msg,
                                    String toUser,HashMap<String,Object> variables){
        try{
            OvTaskEntity task=ovTaskEntityMapper.ovTaskEntity(taskId);
            if(task.getAssignee_()==null){
                taskRuntime.claim(TaskPayloadBuilder.claim().withTaskId(taskId).build());
            }

            OvTaskEntity ovTaskEntity = task;
            ovTaskEntity.setAssignee_(toUser);
            ovTaskEntity.setClaim_time_(DateTime.now().toString("yyyy-MM-dd hh:mm:ss"));

            //执行加签
            taskRuntime.addCandidateUsers(TaskPayloadBuilder.addCandidateUsers().withTaskId(taskId)
                    .withCandidateUser(toUser).build());
            //更新执行人
            ovTaskEntityMapper.setTaskStatus(ovTaskEntity);
            //增加轨迹
            this.addTaskInstTrack(processInstanceId,task,"countersign",Msg);

            ProcessTaskParams processTaskParams=new ProcessTaskParams();
            processTaskParams.setVariables(variables);
            processTaskParams.setTaskId(taskId);
            processTaskParams.setProcessInstanceId(processInstanceId);
            processTaskParams.setMsg(Msg);
            this.setApprovalTrack(ovTaskEntity.getTask_def_key_(),ovTaskEntity.getName_(),processTaskParams,4,"加签");
            return ovTaskEntity;
        }catch (Exception ex){
            return new OvTaskEntity();
            //mybatis数据库回滚事物，TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }

    /**
     * 不同意
     * @param processInstanceId
     * @param taskId
     * @param Msg
     * @param variables
     */
    @Override
    public void refuse(String processInstanceId,String taskId,String Msg,HashMap<String,Object> variables){
        OvTaskEntity ovTaskEntity=ovTaskEntityMapper.ovTaskEntity(taskId);
        try{
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            String username = authentication.getName();
            ovTaskEntityMapper.delete(ovTaskEntity);
            ovTaskEntity.setAssignee_(username);
            //增加历史记录
            this.addTaskInstTrack(processInstanceId,ovTaskEntity,"refuse",Msg);

            ProcessTaskParams processTaskParams=new ProcessTaskParams();
            processTaskParams.setVariables(variables);
            processTaskParams.setTaskId(taskId);
            processTaskParams.setProcessInstanceId(processInstanceId);
            processTaskParams.setMsg(Msg);
            this.setApprovalTrack(ovTaskEntity.getTask_def_key_(),ovTaskEntity.getName_(),processTaskParams,5,"不同意");
        }
        catch (Exception ex){
            ovTaskEntityMapper.setTaskStatus(ovTaskEntity);
        }
    }

    /**
     * 跳转
     * @param processInstanceId
     * @param taskId
     * @param variables
     */
    @Override
    public void jump(String processInstanceId,String taskId,HashMap<String,Object> variables){

    }

    /**
     * 手动结束
     * @param processInstanceId
     * @param taskId
     * @param Msg
     * @param variables
     */
    @Override
    public void setEndTask(String processInstanceId,String taskId,String Msg,
                           HashMap<String,Object> variables){
        OvTaskEntity ovTaskEntity=ovTaskEntityMapper.ovTaskEntity(taskId);
        try{
            taskRuntime.delete(TaskPayloadBuilder.delete().withTaskId(taskId).build());
            //增加历史记录
            this.addTaskInstTrack(processInstanceId,ovTaskEntity,"setEndTask",Msg);

            ProcessTaskParams processTaskParams=new ProcessTaskParams();
            processTaskParams.setVariables(variables);
            processTaskParams.setTaskId(taskId);
            processTaskParams.setProcessInstanceId(processInstanceId);
            processTaskParams.setMsg(Msg);
            this.setApprovalTrack(ovTaskEntity.getTask_def_key_(),ovTaskEntity.getName_(),processTaskParams,6,"手动结束");
        }
        catch (Exception ex){
            ovTaskEntityMapper.setTaskStatus(ovTaskEntity);
        }
    }
    @Override
    public List<TaskInstEntity> getUserTaskTrack(String processInstanceId){
        List<TaskInstEntity> taskInstEntities= taskInstEntityMapper.getUserTaskTrack(processInstanceId);
        return taskInstEntities;
    }

    /**
     * 增加历史处理轨迹
     * @param processInstanceId
     * @param ovTaskEntity
     * @param status
     * @param msg
     */
    @Override
    public void addTaskInstTrack(String processInstanceId,OvTaskEntity ovTaskEntity,String status,
                                 String msg){
        String countersignMyPk=UUID.randomUUID().toString();
        try{
            //增加一条历史记录
            TaskInstEntity taskInstEntity=new TaskInstEntity();
            taskInstEntity.setId_(countersignMyPk);
            taskInstEntity.setProc_def_id_(ovTaskEntity.getProc_def_id_());
            taskInstEntity.setProc_inst_id_(processInstanceId);
            taskInstEntity.setTask_def_key_(ovTaskEntity.getTask_def_key_());
            taskInstEntity.setExecution_id_(ovTaskEntity.getExecution_id_());
            taskInstEntity.setName_(ovTaskEntity.getName_());
            taskInstEntity.setParent_task_id_(ovTaskEntity.getParent_task_id());
            taskInstEntity.setDescription_(ovTaskEntity.getDescription_());
            taskInstEntity.setOwner_(ovTaskEntity.getOwner_());
            taskInstEntity.setAssignee_(ovTaskEntity.getAssignee_());
            taskInstEntity.setStart_time_(ovTaskEntity.getCreate_time_());
            taskInstEntity.setClaim_time_(ovTaskEntity.getClaim_time_());
            taskInstEntity.setEnd_time_(DateTime.now().toString("yyyy-MM-dd hh:mm:ss"));

            //计算用时
            DateFormat startTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date startDate=startTime.parse(ovTaskEntity.getCreate_time_());
            Date endDate=startTime.parse(DateTime.now().toString("yyyy-MM-dd hh:mm:ss"));
            long duration=endDate.getTime()-startDate.getTime();

            taskInstEntity.setDuration_(duration);
            taskInstEntity.setPriority_(ovTaskEntity.getPriority_());
            taskInstEntity.setDue_date_(ovTaskEntity.getDue_date_());
            taskInstEntity.setForm_key_(ovTaskEntity.getForm_key_());
            taskInstEntity.setCategory_(ovTaskEntity.getCategory_());
            taskInstEntity.setTenant_id_(ovTaskEntity.getTenant_id_());
            taskInstEntity.setTask_id_(ovTaskEntity.getId_());
            taskInstEntity.setAct_id_(ovTaskEntity.getTask_def_key_());
            taskInstEntity.setAct_name_(ovTaskEntity.getName_());
            //操作类型
            taskInstEntity.setAct_type_(status);
            //增加任务轨迹
            taskInstEntityMapper.addTaskInstTrack(taskInstEntity);
        }
        catch (Exception ex){
            taskInstEntityMapper.deleteInstTrack(countersignMyPk);
        }
    }
    @Override
    public String sendReceiceTask(String processInstanceId, String taskKey, String executionId){
        //获取流程定义模版
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstanceId);
        //获取流程信息
        FlowElement flowElement = bpmnModel.getFlowElement(taskKey);
        ReceiveTask receiveTask=(ReceiveTask) flowElement;
        List<SequenceFlow> outgoingFlows = receiveTask.getOutgoingFlows();
        //获取用户任务，获取下一步到达的节点，也可能是网关
        FlowElement targetFlowElement = outgoingFlows.get(0).getTargetFlowElement();

        //获取任务信息
        HashMap<String,Object> variables=new HashMap<>();
        //判断下一步是任务节点还是网关
        //如果是 排他网关（条件分支，根据条件判断下一步的任务节点）
        if(targetFlowElement instanceof ExclusiveGateway){
            //获取排他网关分支对象
            List<SequenceFlow> exclusiveGateway=((ExclusiveGateway) targetFlowElement).getOutgoingFlows();
            //循环判断条件
            for(SequenceFlow sf:exclusiveGateway){
                //获取条件表达式
                String gateway=sf.getConditionExpression();
                //使用JUEL表达式进行判断
                ExpressionFactory factory=new ExpressionFactoryImpl();
                SimpleContext context = new SimpleContext();
                //将参数写入JUEL表达式
                for(String key:variables.keySet()){
                    context.setVariable(key, factory.createValueExpression(variables.get(key), String.class));
                }
                //执行判断，设置返回 boolean类型
                ValueExpression isPass = factory.createValueExpression(context, gateway, boolean.class);
                //如果是true，说明满足此分支路线
                if((Boolean)isPass.getValue(context)){
                    //转换成用户任务对象
                    UserTask gateTask=(UserTask)sf.getTargetFlowElement();
                    //获取处理人规则
                    String candidateUsers=gateTask.getCandidateUsers().get(0);
                    String ruleName=candidateUsers.replace("$","");
                    ruleName=ruleName.replace("{","");
                    ruleName=ruleName.replace("}","");
                    ruleName=ruleName.replace(gateTask.getId(),"");
                    //获取处理人
                    variables=getUserInfoByTaskIdAndRuleName(gateTask.getId(),ruleName,variables,processInstanceId);

                    //多实例处理规则，如果是 时序多重事件
                    if(gateTask.getBehavior() instanceof SequentialMultiInstanceBehavior){
                        SequentialMultiInstanceBehavior sequentialMultiInstanceBehavior=(SequentialMultiInstanceBehavior)gateTask.getBehavior();
                        JuelExpression juelExpression=(JuelExpression)sequentialMultiInstanceBehavior.getCollectionExpression();
                        //获取多实例处理规则
                        String juelExpressionText=juelExpression.getExpressionText();
                        String expressionText=juelExpressionText.replace("$","");
                        expressionText=expressionText.replace("{","");
                        expressionText=expressionText.replace("}","");
                        expressionText=expressionText.replace(gateTask.getId(),"");
                        variables=getUserInfoByTaskIdAndRuleName(gateTask.getId(),expressionText,variables,processInstanceId);
                    }
                    //多实例处理规则，如果是 并行多重事件
                    if(gateTask.getBehavior() instanceof ParallelMultiInstanceBehavior){
                        ParallelMultiInstanceBehavior parallelMultiInstanceBehavior=(ParallelMultiInstanceBehavior)gateTask.getBehavior();
                        JuelExpression juelExpression=(JuelExpression)parallelMultiInstanceBehavior.getCollectionExpression();
                        //获取多实例处理规则
                        String juelExpressionText=juelExpression.getExpressionText();
                        String expressionText=juelExpressionText.replace("$","");
                        expressionText=expressionText.replace("{","");
                        expressionText=expressionText.replace("}","");
                        expressionText=expressionText.replace(gateTask.getId(),"");
                        variables=getUserInfoByTaskIdAndRuleName(gateTask.getId(),expressionText,variables,processInstanceId);
                    }
                }
            }
        }
        //如果是并行网关(同时发送给多个任务节点，并发)
        else if(targetFlowElement instanceof ParallelGateway){
            //获取并行网关分支对象
            List<SequenceFlow> parallelGateway=((ParallelGateway) targetFlowElement).getOutgoingFlows();
            for(SequenceFlow sf:parallelGateway){
                //转换成用户任务对象
                UserTask parallelTask=(UserTask)sf.getTargetFlowElement();
                //获取处理人规则
                String candidateUsers=parallelTask.getCandidateUsers().get(0);
                String ruleName=candidateUsers.replace("$","");
                ruleName=ruleName.replace("{","");
                ruleName=ruleName.replace("}","");
                ruleName=ruleName.replace(parallelTask.getId(),"");
                //获取处理人
                variables=getUserInfoByTaskIdAndRuleName(parallelTask.getId(),ruleName,variables,processInstanceId);

                //多实例处理规则
                if(parallelTask.getBehavior() instanceof SequentialMultiInstanceBehavior){
                    SequentialMultiInstanceBehavior sequentialMultiInstanceBehavior=(SequentialMultiInstanceBehavior)parallelTask.getBehavior();
                    JuelExpression juelExpression=(JuelExpression)sequentialMultiInstanceBehavior.getCollectionExpression();
                    //获取多实例处理规则
                    String juelExpressionText=juelExpression.getExpressionText();
                    String expressionText=juelExpressionText.replace("$","");
                    expressionText=expressionText.replace("{","");
                    expressionText=expressionText.replace("}","");
                    expressionText=expressionText.replace(parallelTask.getId(),"");
                    variables=getUserInfoByTaskIdAndRuleName(parallelTask.getId(),expressionText,variables,processInstanceId);
                }
                //多实例处理规则，如果是 并行多重事件
                if(parallelTask.getBehavior() instanceof ParallelMultiInstanceBehavior){
                    ParallelMultiInstanceBehavior parallelMultiInstanceBehavior=(ParallelMultiInstanceBehavior)parallelTask.getBehavior();
                    JuelExpression juelExpression=(JuelExpression)parallelMultiInstanceBehavior.getCollectionExpression();
                    //获取多实例处理规则
                    String juelExpressionText=juelExpression.getExpressionText();
                    String expressionText=juelExpressionText.replace("$","");
                    expressionText=expressionText.replace("{","");
                    expressionText=expressionText.replace("}","");
                    expressionText=expressionText.replace(parallelTask.getId(),"");
                    variables=getUserInfoByTaskIdAndRuleName(parallelTask.getId(),expressionText,variables,processInstanceId);
                }
            }
        }
        //如果是相容网关（发送给满足条件的多个任务节点）
        else if(targetFlowElement instanceof InclusiveGateway){
            //获取相容网关分支对象
            List<SequenceFlow> inclusiveGateway=((InclusiveGateway) targetFlowElement).getOutgoingFlows();
            for(SequenceFlow sf:inclusiveGateway){
                //获取条件表达式
                String gateway=sf.getConditionExpression();
                if(SystemConfig.IsNullOrEmpty(gateway)){
                    //获取处理人规则
                    UserTask gateTask = (UserTask) sf.getTargetFlowElement();
                    //获取处理人规则
                    String candidateUsers=gateTask.getCandidateUsers().get(0);
                    String ruleName=candidateUsers.replace("$","");
                    ruleName=ruleName.replace("{","");
                    ruleName=ruleName.replace("}","");
                    ruleName=ruleName.replace(gateTask.getId(),"");
                    //获取处理人
                    variables=getUserInfoByTaskIdAndRuleName(gateTask.getId(),ruleName,variables,processInstanceId);

                    //多实例处理规则
                    if(gateTask.getBehavior() instanceof SequentialMultiInstanceBehavior){
                        SequentialMultiInstanceBehavior sequentialMultiInstanceBehavior=(SequentialMultiInstanceBehavior)gateTask.getBehavior();
                        JuelExpression juelExpression=(JuelExpression)sequentialMultiInstanceBehavior.getCollectionExpression();
                        //获取多实例处理规则
                        String juelExpressionText=juelExpression.getExpressionText();
                        String expressionText=juelExpressionText.replace("$","");
                        expressionText=expressionText.replace("{","");
                        expressionText=expressionText.replace("}","");
                        expressionText=expressionText.replace(gateTask.getId(),"");
                        variables=getUserInfoByTaskIdAndRuleName(gateTask.getId(),expressionText,variables,processInstanceId);
                    }
                    //多实例处理规则，如果是 并行多重事件
                    if(gateTask.getBehavior() instanceof ParallelMultiInstanceBehavior){
                        ParallelMultiInstanceBehavior parallelMultiInstanceBehavior=(ParallelMultiInstanceBehavior)gateTask.getBehavior();
                        JuelExpression juelExpression=(JuelExpression)parallelMultiInstanceBehavior.getCollectionExpression();
                        //获取多实例处理规则
                        String juelExpressionText=juelExpression.getExpressionText();
                        String expressionText=juelExpressionText.replace("$","");
                        expressionText=expressionText.replace("{","");
                        expressionText=expressionText.replace("}","");
                        expressionText=expressionText.replace(gateTask.getId(),"");
                        variables=getUserInfoByTaskIdAndRuleName(gateTask.getId(),expressionText,variables,processInstanceId);
                    }
                }
                else {
                    //使用JUEL表达式进行判断
                    ExpressionFactory factory = new ExpressionFactoryImpl();
                    SimpleContext context = new SimpleContext();
                    //将参数写入JUEL表达式
                    for (String key : variables.keySet()) {
                        context.setVariable(key, factory.createValueExpression(variables.get(key), String.class));
                    }
                    //执行判断，设置返回 boolean类型
                    ValueExpression isPass = factory.createValueExpression(context, gateway, boolean.class);
                    //如果是true，说明满足此分支路线
                    if ((Boolean) isPass.getValue(context)) {
                        //转换成用户任务对象
                        UserTask gateTask = (UserTask) sf.getTargetFlowElement();
                        //获取处理人规则
                        String candidateUsers=gateTask.getCandidateUsers().get(0);
                        String ruleName=candidateUsers.replace("$","");
                        ruleName=ruleName.replace("{","");
                        ruleName=ruleName.replace("}","");
                        ruleName=ruleName.replace(gateTask.getId(),"");
                        //获取处理人
                        variables=getUserInfoByTaskIdAndRuleName(gateTask.getId(),ruleName,variables,processInstanceId);
                        //多实例处理规则
                        if(gateTask.getBehavior() instanceof SequentialMultiInstanceBehavior){
                            SequentialMultiInstanceBehavior sequentialMultiInstanceBehavior=(SequentialMultiInstanceBehavior)gateTask.getBehavior();
                            JuelExpression juelExpression=(JuelExpression)sequentialMultiInstanceBehavior.getCollectionExpression();
                            //获取多实例处理规则
                            String juelExpressionText=juelExpression.getExpressionText();
                            String expressionText=juelExpressionText.replace("$","");
                            expressionText=expressionText.replace("{","");
                            expressionText=expressionText.replace("}","");
                            expressionText=expressionText.replace(gateTask.getId(),"");
                            variables=getUserInfoByTaskIdAndRuleName(gateTask.getId(),expressionText,variables,processInstanceId);
                        }
                        //多实例处理规则，如果是 并行多重事件
                        if(gateTask.getBehavior() instanceof ParallelMultiInstanceBehavior){
                            ParallelMultiInstanceBehavior parallelMultiInstanceBehavior=(ParallelMultiInstanceBehavior)gateTask.getBehavior();
                            JuelExpression juelExpression=(JuelExpression)parallelMultiInstanceBehavior.getCollectionExpression();
                            //获取多实例处理规则
                            String juelExpressionText=juelExpression.getExpressionText();
                            String expressionText=juelExpressionText.replace("$","");
                            expressionText=expressionText.replace("{","");
                            expressionText=expressionText.replace("}","");
                            expressionText=expressionText.replace(gateTask.getId(),"");
                            variables=getUserInfoByTaskIdAndRuleName(gateTask.getId(),expressionText,variables,processInstanceId);
                        }
                    }
                }
            }
        }
        //如果是结束节点
        else if(targetFlowElement instanceof EndEvent){
            try {
                //获取子流程对象
                SubProcess subProcess = (SubProcess) targetFlowElement.getParentContainer();
                List<SequenceFlow> subOutgoingFlows = subProcess.getOutgoingFlows();
                //结束后面还有连接线，说明这是子流程结束，需要获取父流程的下一步节点信息
                if (subOutgoingFlows.size() > 0) {
                    //获取任务对象
                    UserTask subTask = (UserTask) subOutgoingFlows.get(0).getTargetFlowElement();
                    //获取处理人规则
                    String candidateUsers=subTask.getCandidateUsers().get(0);
                    String ruleName=candidateUsers.replace("$","");
                    ruleName=ruleName.replace("{","");
                    ruleName=ruleName.replace("}","");
                    ruleName=ruleName.replace(subTask.getId(),"");
                    //获取处理人
                    variables=getUserInfoByTaskIdAndRuleName(subTask.getId(),ruleName,variables,processInstanceId);

                    //多实例处理规则
                    if(subTask.getBehavior() instanceof SequentialMultiInstanceBehavior){
                        SequentialMultiInstanceBehavior sequentialMultiInstanceBehavior=(SequentialMultiInstanceBehavior)subTask.getBehavior();
                        JuelExpression juelExpression=(JuelExpression)sequentialMultiInstanceBehavior.getCollectionExpression();
                        //获取多实例处理规则
                        String juelExpressionText=juelExpression.getExpressionText();
                        String expressionText=juelExpressionText.replace("$","");
                        expressionText=expressionText.replace("{","");
                        expressionText=expressionText.replace("}","");
                        expressionText=expressionText.replace(subTask.getId(),"");
                        variables=getUserInfoByTaskIdAndRuleName(subTask.getId(),expressionText,variables,processInstanceId);
                    }
                    //多实例处理规则，如果是 并行多重事件
                    if(subTask.getBehavior() instanceof ParallelMultiInstanceBehavior){
                        ParallelMultiInstanceBehavior parallelMultiInstanceBehavior=(ParallelMultiInstanceBehavior)subTask.getBehavior();
                        JuelExpression juelExpression=(JuelExpression)parallelMultiInstanceBehavior.getCollectionExpression();
                        //获取多实例处理规则
                        String juelExpressionText=juelExpression.getExpressionText();
                        String expressionText=juelExpressionText.replace("$","");
                        expressionText=expressionText.replace("{","");
                        expressionText=expressionText.replace("}","");
                        expressionText=expressionText.replace(subTask.getId(),"");
                        variables=getUserInfoByTaskIdAndRuleName(subTask.getId(),expressionText,variables,processInstanceId);
                    }
                }
            }//报错说明这是普通流程的结束
            catch (Exception e) {
                if(redisUtils.exists(processInstanceId+"_end")){
                    redisUtils.remove(processInstanceId+"_end");
                }
                redisUtils.set(processInstanceId+"_sms","流程已结束。");
            }
        }
        //如果是子流程
        else if(targetFlowElement instanceof SubProcess){
            //获取子流程对象
            Collection<FlowElement> subProcess=((SubProcess) targetFlowElement).getFlowElements();
            for (FlowElement fl : subProcess) {
                //判断是否是子流程开始节点
                if (fl instanceof StartEvent) {
                    List<SequenceFlow> subOutgoingFlows =((StartEvent) fl).getOutgoingFlows();
                    //取子流程中开始节点后面的第一个usertask
                    UserTask subTask = (UserTask) subOutgoingFlows.get(0).getTargetFlowElement();
                    //获取处理人规则
                    String candidateUsers=subTask.getCandidateUsers().get(0);
                    String ruleName=candidateUsers.replace("$","");
                    ruleName=ruleName.replace("{","");
                    ruleName=ruleName.replace("}","");
                    ruleName=ruleName.replace(subTask.getId(),"");
                    //获取处理人
                    variables=getUserInfoByTaskIdAndRuleName(subTask.getId(),ruleName,variables,processInstanceId);
                    //多实例处理规则
                    if(subTask.getBehavior() instanceof SequentialMultiInstanceBehavior){
                        SequentialMultiInstanceBehavior sequentialMultiInstanceBehavior=(SequentialMultiInstanceBehavior)subTask.getBehavior();
                        JuelExpression juelExpression=(JuelExpression)sequentialMultiInstanceBehavior.getCollectionExpression();
                        //获取多实例处理规则
                        String juelExpressionText=juelExpression.getExpressionText();
                        String expressionText=juelExpressionText.replace("$","");
                        expressionText=expressionText.replace("{","");
                        expressionText=expressionText.replace("}","");
                        expressionText=expressionText.replace(subTask.getId(),"");
                        variables=getUserInfoByTaskIdAndRuleName(subTask.getId(),expressionText,variables,processInstanceId);
                    }
                    //多实例处理规则，如果是 并行多重事件
                    if(subTask.getBehavior() instanceof ParallelMultiInstanceBehavior){
                        ParallelMultiInstanceBehavior parallelMultiInstanceBehavior=(ParallelMultiInstanceBehavior)subTask.getBehavior();
                        JuelExpression juelExpression=(JuelExpression)parallelMultiInstanceBehavior.getCollectionExpression();
                        //获取多实例处理规则
                        String juelExpressionText=juelExpression.getExpressionText();
                        String expressionText=juelExpressionText.replace("$","");
                        expressionText=expressionText.replace("{","");
                        expressionText=expressionText.replace("}","");
                        expressionText=expressionText.replace(subTask.getId(),"");
                        variables=getUserInfoByTaskIdAndRuleName(subTask.getId(),expressionText,variables,processInstanceId);
                    }
                }
            }
        }
        //如果是等待任务
        else if(targetFlowElement instanceof ReceiveTask){

        }
        //如果是调用任务
        else if(targetFlowElement instanceof CallActivity){
            // todo:1.调用子流程（数据同步、父流程进入下一步？父流程暂停？子流程结束后父流程进入下一步？）
            // todo:2.调用webapi
            // todo:3.调用sql
            CallActivity callActivity = (CallActivity) targetFlowElement;
            List<SequenceFlow> callActivityOutgoingFlows = callActivity.getOutgoingFlows();
            UserTask callActivityTask = (UserTask) callActivityOutgoingFlows.get(0).getTargetFlowElement();
            //获取处理人规则
            String candidateUsers=callActivityTask.getCandidateUsers().get(0);
            String ruleName=candidateUsers.replace("$","");
            ruleName=ruleName.replace("{","");
            ruleName=ruleName.replace("}","");
            ruleName=ruleName.replace(callActivityTask.getId(),"");
            //获取处理人
            variables=getUserInfoByTaskIdAndRuleName(callActivityTask.getId(),ruleName,variables,processInstanceId);
            //多实例处理规则
            if(callActivityTask.getBehavior() instanceof SequentialMultiInstanceBehavior){
                SequentialMultiInstanceBehavior sequentialMultiInstanceBehavior=(SequentialMultiInstanceBehavior)callActivityTask.getBehavior();
                JuelExpression juelExpression=(JuelExpression)sequentialMultiInstanceBehavior.getCollectionExpression();
                //获取多实例处理规则
                String juelExpressionText=juelExpression.getExpressionText();
                String expressionText=juelExpressionText.replace("$","");
                expressionText=expressionText.replace("{","");
                expressionText=expressionText.replace("}","");
                expressionText=expressionText.replace(callActivityTask.getId(),"");
                variables=getUserInfoByTaskIdAndRuleName(callActivityTask.getId(),expressionText,variables,processInstanceId);
            }
            //多实例处理规则，如果是 并行多重事件
            if(callActivityTask.getBehavior() instanceof ParallelMultiInstanceBehavior){
                ParallelMultiInstanceBehavior parallelMultiInstanceBehavior=(ParallelMultiInstanceBehavior)callActivityTask.getBehavior();
                JuelExpression juelExpression=(JuelExpression)parallelMultiInstanceBehavior.getCollectionExpression();
                //获取多实例处理规则
                String juelExpressionText=juelExpression.getExpressionText();
                String expressionText=juelExpressionText.replace("$","");
                expressionText=expressionText.replace("{","");
                expressionText=expressionText.replace("}","");
                expressionText=expressionText.replace(callActivityTask.getId(),"");
                variables=getUserInfoByTaskIdAndRuleName(callActivityTask.getId(),expressionText,variables,processInstanceId);
            }
        }
        else {
            UserTask defUserTask=(UserTask) targetFlowElement;
            //获取处理人规则
            String candidateUsers=defUserTask.getCandidateUsers().get(0);
            String ruleName=candidateUsers.replace("$","");
            ruleName=ruleName.replace("{","");
            ruleName=ruleName.replace("}","");
            ruleName=ruleName.replace(defUserTask.getId(),"");
            //获取处理人
            variables=getUserInfoByTaskIdAndRuleName(defUserTask.getId(),ruleName,variables,processInstanceId);
            //多实例处理规则
            if(defUserTask.getBehavior() instanceof SequentialMultiInstanceBehavior){
                SequentialMultiInstanceBehavior sequentialMultiInstanceBehavior=(SequentialMultiInstanceBehavior)defUserTask.getBehavior();
                JuelExpression juelExpression=(JuelExpression)sequentialMultiInstanceBehavior.getCollectionExpression();
                //获取多实例处理规则
                String juelExpressionText=juelExpression.getExpressionText();
                String expressionText=juelExpressionText.replace("$","");
                expressionText=expressionText.replace("{","");
                expressionText=expressionText.replace("}","");
                expressionText=expressionText.replace(defUserTask.getId(),"");
                variables=getUserInfoByTaskIdAndRuleName(defUserTask.getId(),expressionText,variables,processInstanceId);
            }
            //多实例处理规则，如果是 并行多重事件
            if(defUserTask.getBehavior() instanceof ParallelMultiInstanceBehavior){
                ParallelMultiInstanceBehavior parallelMultiInstanceBehavior=(ParallelMultiInstanceBehavior)defUserTask.getBehavior();
                JuelExpression juelExpression=(JuelExpression)parallelMultiInstanceBehavior.getCollectionExpression();
                //获取多实例处理规则
                String juelExpressionText=juelExpression.getExpressionText();
                String expressionText=juelExpressionText.replace("$","");
                expressionText=expressionText.replace("{","");
                expressionText=expressionText.replace("}","");
                expressionText=expressionText.replace(defUserTask.getId(),"");
                variables=getUserInfoByTaskIdAndRuleName(defUserTask.getId(),expressionText,variables,processInstanceId);
            }
        }

        //向等待节点发送消息
        runtimeService.setVariables(executionId,variables);
        runtimeService.trigger(executionId);
        return "发送成功";
    }
    @Override
    public List<UserTask> getNextTaskInfo(String procInstId,String taskid,HashMap<String,Object> variables){
        List<UserTask> userTaskList=new ArrayList<>();
        try{
            //获取当前流程信息
            String processDefinitionId = historyService.createHistoricProcessInstanceQuery()
                    .processInstanceId(procInstId)
                    .singleResult()
                    .getProcessDefinitionId();
            //获取当前任务信息
            org.activiti.engine.task.Task task=taskService.createTaskQuery().taskId(taskid).singleResult();

            //获取流程定义模版
            BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
            //获取流程信息
            FlowElement flowElement = bpmnModel.getFlowElement(task.getTaskDefinitionKey());
            //获取用户任务
            UserTask userTask = (UserTask) flowElement;
            //获取下一步到达的节点，也可能是网关
            List<SequenceFlow> outgoingFlows = userTask.getOutgoingFlows();
            //下一步必须是一个节点或网关，不支持不通过网关就到达多个节点的模式，因此只取第一个对象
            // todo:不通过网关就到达多个节点的模式待认证
            FlowElement targetFlowElement = outgoingFlows.get(0).getTargetFlowElement();
            //判断下一步是任务节点还是网关
            //如果是 排他网关（条件分支，根据条件判断下一步的任务节点）
            if(targetFlowElement instanceof ExclusiveGateway){
                //获取排他网关分支对象
                List<SequenceFlow> exclusiveGateway=((ExclusiveGateway) targetFlowElement).getOutgoingFlows();
                //循环判断条件
                for(SequenceFlow sf:exclusiveGateway){
                    //获取条件表达式
                    String gateway=sf.getConditionExpression();
                    //使用JUEL表达式进行判断
                    ExpressionFactory factory=new ExpressionFactoryImpl();
                    SimpleContext context = new SimpleContext();
                    //将参数写入JUEL表达式
                    for(String key:variables.keySet()){
                        context.setVariable(key, factory.createValueExpression(variables.get(key), String.class));
                    }
                    //执行判断，设置返回 boolean类型
                    ValueExpression isPass = factory.createValueExpression(context, gateway, boolean.class);
                    //如果是true，说明满足此分支路线
                    if((Boolean)isPass.getValue(context)){
                        //转换成用户任务
                        UserTask gateTask=(UserTask)sf.getTargetFlowElement();
                        userTaskList.add(gateTask);
                    }
                }
            }
            //如果是并行网关(同时发送给多个任务节点，并发)
            else if(targetFlowElement instanceof ParallelGateway){
                //获取并行网关分支对象
                List<SequenceFlow> parallelGateway=((ParallelGateway) targetFlowElement).getOutgoingFlows();
                for(SequenceFlow sf:parallelGateway){
                    UserTask parallelTask=(UserTask)sf.getTargetFlowElement();
                    userTaskList.add(parallelTask);
                }
            }
            //如果是相容网关（发送给满足条件的多个任务节点）
            else if(targetFlowElement instanceof InclusiveGateway){
                //获取相容网关分支对象
                List<SequenceFlow> inclusiveGateway=((InclusiveGateway) targetFlowElement).getOutgoingFlows();
                for(SequenceFlow sf:inclusiveGateway){
                    //获取条件表达式
                    String gateway=sf.getConditionExpression();
                    if(SystemConfig.IsNullOrEmpty(gateway)){
                        UserTask gateTask = (UserTask) sf.getTargetFlowElement();
                        userTaskList.add(gateTask);
                    }
                    else {
                        //使用JUEL表达式进行判断
                        ExpressionFactory factory = new ExpressionFactoryImpl();
                        SimpleContext context = new SimpleContext();
                        //将参数写入JUEL表达式
                        for (String key : variables.keySet()) {
                            context.setVariable(key, factory.createValueExpression(variables.get(key), String.class));
                        }
                        //执行判断，设置返回 boolean类型
                        ValueExpression isPass = factory.createValueExpression(context, gateway, boolean.class);
                        //如果是true，说明满足此分支路线
                        if ((Boolean) isPass.getValue(context)) {
                            //转换成用户任务
                            UserTask gateTask = (UserTask) sf.getTargetFlowElement();
                            userTaskList.add(gateTask);
                        }
                    }
                }
            }
            //如果是结束节点
            else if(targetFlowElement instanceof EndEvent){
                try {
                    //获取子流程对象
                    SubProcess subProcess = (SubProcess) targetFlowElement.getParentContainer();
                    List<SequenceFlow> subOutgoingFlows = subProcess.getOutgoingFlows();
                    //结束后面还有连接线，说明这是子流程结束，需要获取父流程的下一步节点信息
                    if (subOutgoingFlows.size() > 0) {
                        UserTask subTask = (UserTask) subOutgoingFlows.get(0).getTargetFlowElement();
                        userTaskList.add(subTask);
                    }
                }//报错说明这是普通流程的结束
                catch (Exception e) {
                    UserTask endUserTask=new UserTask();
                    endUserTask.setId("endEvent");
                    endUserTask.setName("结束");
                    userTaskList.add(endUserTask);

                    if(redisUtils.exists(procInstId+"_end")){
                        redisUtils.remove(procInstId+"_end");
                    }
                    redisUtils.set(procInstId+"_sms","流程已结束。");
                }
            }
            //如果是子流程
            else if(targetFlowElement instanceof SubProcess){
                //获取子流程对象
                Collection<FlowElement> subProcess=((SubProcess) targetFlowElement).getFlowElements();
                for (FlowElement fl : subProcess) {
                    //判断是否是子流程开始节点
                    if (fl instanceof StartEvent) {
                        List<SequenceFlow> subOutgoingFlows =((StartEvent) fl).getOutgoingFlows();
                        //取子流程中开始节点后面的第一个usertask
                        UserTask subTask = (UserTask) subOutgoingFlows.get(0).getTargetFlowElement();
                        userTaskList.add(subTask);
                    }
                }
            }
            //如果是等待任务
            else if(targetFlowElement instanceof ReceiveTask){
                UserTask receiveTask=new UserTask();
                receiveTask.setId("receiveTask");
                receiveTask.setName("等待任务节点");
                userTaskList.add(receiveTask);
            }
            //如果是调用任务
            else if(targetFlowElement instanceof CallActivity){
                // todo:1.调用子流程（数据同步、父流程进入下一步？父流程暂停？子流程结束后父流程进入下一步？）
                // todo:2.调用webapi
                // todo:3.调用sql
                CallActivity callActivity = (CallActivity) targetFlowElement;
                List<SequenceFlow> callActivityOutgoingFlows = callActivity.getOutgoingFlows();
                UserTask callActivityTask = (UserTask) callActivityOutgoingFlows.get(0).getTargetFlowElement();

                UserTask callActivityUserTask=new UserTask();
                callActivityUserTask.setId("callActivityTask");
                callActivityUserTask.setName("调用任务节点");
                userTaskList.add(callActivityUserTask);

                userTaskList.add(callActivityTask);
            }
            else {
                userTaskList.add((UserTask) targetFlowElement);
            }
            //返回下一步节点
            return userTaskList;
        }
        catch(Exception ex) {
            return userTaskList;
        }
    }
    @Override
    public HashMap<String,Object> getNextUserInfo(String procInstId,String taskid,HashMap<String,Object> variables){
        try{
            //获取当前流程信息
            String processDefinitionId = historyService.createHistoricProcessInstanceQuery()
                    .processInstanceId(procInstId)
                    .singleResult()
                    .getProcessDefinitionId();
            //获取当前任务信息
            org.activiti.engine.task.Task task=taskService.createTaskQuery().taskId(taskid).singleResult();

            //获取流程定义模版
            BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
            //获取流程信息
            FlowElement flowElement = bpmnModel.getFlowElement(task.getTaskDefinitionKey());
            //获取用户任务
            UserTask userTask = (UserTask) flowElement;
            //判断当前节点是否是会签节点
            try {
                ParallelMultiInstanceBehavior pmiBehavior = (ParallelMultiInstanceBehavior) userTask.getBehavior();
                String et = pmiBehavior.getCollectionVariable();
                et = et.replace(userTask.getId(), "");
                variables = getUserInfoByTaskIdAndRuleName(userTask.getId(), et, variables, procInstId);
            }//继续执行
            catch (Exception ex){}
            try {
                SequentialMultiInstanceBehavior smiBehavior=(SequentialMultiInstanceBehavior)userTask.getBehavior();
                String et = smiBehavior.getCollectionVariable();
                et = et.replace(userTask.getId(), "");
                variables = getUserInfoByTaskIdAndRuleName(userTask.getId(), et, variables, procInstId);
            }//继续执行
            catch (Exception ex){}
            //获取下一步到达的节点，也可能是网关
            List<SequenceFlow> outgoingFlows = userTask.getOutgoingFlows();
            //下一步必须是一个节点或网关，不支持不通过网关就到达多个节点的模式，因此只取第一个对象
            // todo:不通过网关就到达多个节点的模式待认证
            FlowElement targetFlowElement = outgoingFlows.get(0).getTargetFlowElement();
            //判断下一步是任务节点还是网关
            //如果是 排他网关（条件分支，根据条件判断下一步的任务节点）
            if(targetFlowElement instanceof ExclusiveGateway){
                //获取排他网关分支对象
                List<SequenceFlow> exclusiveGateway=((ExclusiveGateway) targetFlowElement).getOutgoingFlows();
                //循环判断条件
                for(SequenceFlow sf:exclusiveGateway){
                    //获取条件表达式
                    String gateway=sf.getConditionExpression();
                    //使用JUEL表达式进行判断
                    ExpressionFactory factory=new ExpressionFactoryImpl();
                    SimpleContext context = new SimpleContext();
                    //将参数写入JUEL表达式
                    for(String key:variables.keySet()){
                        context.setVariable(key, factory.createValueExpression(variables.get(key), String.class));
                    }
                    //执行判断，设置返回 boolean类型
                    ValueExpression isPass = factory.createValueExpression(context, gateway, boolean.class);
                    //如果是true，说明满足此分支路线
                    if((Boolean)isPass.getValue(context)){
                        //转换成用户任务对象
                        UserTask gateTask=(UserTask)sf.getTargetFlowElement();
                        //获取处理人规则
                        String candidateUsers=gateTask.getCandidateUsers().get(0);
                        String ruleName=candidateUsers.replace("$","");
                        ruleName=ruleName.replace("{","");
                        ruleName=ruleName.replace("}","");
                        ruleName=ruleName.replace(gateTask.getId(),"");
                        //获取处理人
                        variables=getUserInfoByTaskIdAndRuleName(gateTask.getId(),ruleName,variables,procInstId);

                        //多实例处理规则，如果是 时序多重事件
                        if(gateTask.getBehavior() instanceof SequentialMultiInstanceBehavior){
                            SequentialMultiInstanceBehavior sequentialMultiInstanceBehavior=(SequentialMultiInstanceBehavior)gateTask.getBehavior();
                            //获取多实例处理规则
                            String expressionText=sequentialMultiInstanceBehavior.getCollectionVariable();
                            expressionText=expressionText.replace(gateTask.getId(),"");
                            variables=getUserInfoByTaskIdAndRuleName(gateTask.getId(),expressionText,variables,procInstId);
                        }
                        //多实例处理规则，如果是 并行多重事件
                        if(gateTask.getBehavior() instanceof ParallelMultiInstanceBehavior){
                            ParallelMultiInstanceBehavior parallelMultiInstanceBehavior=(ParallelMultiInstanceBehavior)gateTask.getBehavior();
                            //获取多实例处理规则
                            String expressionText=parallelMultiInstanceBehavior.getCollectionVariable();
                            expressionText=expressionText.replace(gateTask.getId(),"");
                            variables=getUserInfoByTaskIdAndRuleName(gateTask.getId(),expressionText,variables,procInstId);
                        }
                    }
                }
            }
            //如果是并行网关(同时发送给多个任务节点，并发)
            else if(targetFlowElement instanceof ParallelGateway){
                //获取并行网关分支对象
                List<SequenceFlow> parallelGateway=((ParallelGateway) targetFlowElement).getOutgoingFlows();
                for(SequenceFlow sf:parallelGateway){
                    //转换成用户任务对象
                    UserTask parallelTask=(UserTask)sf.getTargetFlowElement();
                    //获取处理人规则
                    String candidateUsers=parallelTask.getCandidateUsers().get(0);
                    String ruleName=candidateUsers.replace("$","");
                    ruleName=ruleName.replace("{","");
                    ruleName=ruleName.replace("}","");
                    ruleName=ruleName.replace(parallelTask.getId(),"");
                    //获取处理人
                    variables=getUserInfoByTaskIdAndRuleName(parallelTask.getId(),ruleName,variables,procInstId);

                    //多实例处理规则
                    if(parallelTask.getBehavior() instanceof SequentialMultiInstanceBehavior){
                        SequentialMultiInstanceBehavior sequentialMultiInstanceBehavior=(SequentialMultiInstanceBehavior)parallelTask.getBehavior();
                        //获取多实例处理规则
                        String expressionText=sequentialMultiInstanceBehavior.getCollectionVariable();
                        expressionText=expressionText.replace(parallelTask.getId(),"");
                        variables=getUserInfoByTaskIdAndRuleName(parallelTask.getId(),expressionText,variables,procInstId);
                    }
                    //多实例处理规则，如果是 并行多重事件
                    if(parallelTask.getBehavior() instanceof ParallelMultiInstanceBehavior){
                        ParallelMultiInstanceBehavior parallelMultiInstanceBehavior=(ParallelMultiInstanceBehavior)parallelTask.getBehavior();
                        //获取多实例处理规则
                        String expressionText=parallelMultiInstanceBehavior.getCollectionVariable();
                        expressionText=expressionText.replace(parallelTask.getId(),"");
                        variables=getUserInfoByTaskIdAndRuleName(parallelTask.getId(),expressionText,variables,procInstId);
                    }
                }
            }
            //如果是相容网关（发送给满足条件的多个任务节点）
            else if(targetFlowElement instanceof InclusiveGateway){
                //获取相容网关分支对象
                List<SequenceFlow> inclusiveGateway=((InclusiveGateway) targetFlowElement).getOutgoingFlows();
                for(SequenceFlow sf:inclusiveGateway){
                    //获取条件表达式
                    String gateway=sf.getConditionExpression();
                    if(SystemConfig.IsNullOrEmpty(gateway)){
                        //获取处理人规则
                        UserTask gateTask = (UserTask) sf.getTargetFlowElement();
                        //获取处理人规则
                        String candidateUsers=gateTask.getCandidateUsers().get(0);
                        String ruleName=candidateUsers.replace("$","");
                        ruleName=ruleName.replace("{","");
                        ruleName=ruleName.replace("}","");
                        ruleName=ruleName.replace(gateTask.getId(),"");
                        //获取处理人
                        variables=getUserInfoByTaskIdAndRuleName(gateTask.getId(),ruleName,variables,procInstId);

                        //多实例处理规则
                        if(gateTask.getBehavior() instanceof SequentialMultiInstanceBehavior){
                            SequentialMultiInstanceBehavior sequentialMultiInstanceBehavior=(SequentialMultiInstanceBehavior)gateTask.getBehavior();
                            //获取多实例处理规则
                            String expressionText=sequentialMultiInstanceBehavior.getCollectionVariable();
                            expressionText=expressionText.replace(gateTask.getId(),"");
                            variables=getUserInfoByTaskIdAndRuleName(gateTask.getId(),expressionText,variables,procInstId);
                        }
                        //多实例处理规则，如果是 并行多重事件
                        if(gateTask.getBehavior() instanceof ParallelMultiInstanceBehavior){
                            ParallelMultiInstanceBehavior parallelMultiInstanceBehavior=(ParallelMultiInstanceBehavior)gateTask.getBehavior();
                            //获取多实例处理规则
                            String expressionText=parallelMultiInstanceBehavior.getCollectionVariable();
                            expressionText=expressionText.replace(gateTask.getId(),"");
                            variables=getUserInfoByTaskIdAndRuleName(gateTask.getId(),expressionText,variables,procInstId);
                        }
                    }
                    else {
                        //使用JUEL表达式进行判断
                        ExpressionFactory factory = new ExpressionFactoryImpl();
                        SimpleContext context = new SimpleContext();
                        //将参数写入JUEL表达式
                        for (String key : variables.keySet()) {
                            context.setVariable(key, factory.createValueExpression(variables.get(key), String.class));
                        }
                        //执行判断，设置返回 boolean类型
                        ValueExpression isPass = factory.createValueExpression(context, gateway, boolean.class);
                        //如果是true，说明满足此分支路线
                        if ((Boolean) isPass.getValue(context)) {
                            //转换成用户任务对象
                            UserTask gateTask = (UserTask) sf.getTargetFlowElement();
                            //获取处理人规则
                            String candidateUsers=gateTask.getCandidateUsers().get(0);
                            String ruleName=candidateUsers.replace("$","");
                            ruleName=ruleName.replace("{","");
                            ruleName=ruleName.replace("}","");
                            ruleName=ruleName.replace(gateTask.getId(),"");
                            //获取处理人
                            variables=getUserInfoByTaskIdAndRuleName(gateTask.getId(),ruleName,variables,procInstId);
                            //多实例处理规则
                            if(gateTask.getBehavior() instanceof SequentialMultiInstanceBehavior){
                                SequentialMultiInstanceBehavior sequentialMultiInstanceBehavior=(SequentialMultiInstanceBehavior)gateTask.getBehavior();
                                //获取多实例处理规则
                                String expressionText=sequentialMultiInstanceBehavior.getCollectionVariable();
                                expressionText=expressionText.replace(gateTask.getId(),"");
                                variables=getUserInfoByTaskIdAndRuleName(gateTask.getId(),expressionText,variables,procInstId);
                            }
                            //多实例处理规则，如果是 并行多重事件
                            if(gateTask.getBehavior() instanceof ParallelMultiInstanceBehavior){
                                ParallelMultiInstanceBehavior parallelMultiInstanceBehavior=(ParallelMultiInstanceBehavior)gateTask.getBehavior();
                                //获取多实例处理规则
                                String expressionText=parallelMultiInstanceBehavior.getCollectionVariable();
                                expressionText=expressionText.replace(gateTask.getId(),"");
                                variables=getUserInfoByTaskIdAndRuleName(gateTask.getId(),expressionText,variables,procInstId);
                            }
                        }
                    }
                }
            }
            //如果是结束节点
            else if(targetFlowElement instanceof EndEvent){
                try {
                    //获取子流程对象
                    SubProcess subProcess = (SubProcess) targetFlowElement.getParentContainer();
                    List<SequenceFlow> subOutgoingFlows = subProcess.getOutgoingFlows();
                    //结束后面还有连接线，说明这是子流程结束，需要获取父流程的下一步节点信息
                    if (subOutgoingFlows.size() > 0) {
                        //获取任务对象
                        UserTask subTask = (UserTask) subOutgoingFlows.get(0).getTargetFlowElement();
                        //获取处理人规则
                        String candidateUsers=subTask.getCandidateUsers().get(0);
                        String ruleName=candidateUsers.replace("$","");
                        ruleName=ruleName.replace("{","");
                        ruleName=ruleName.replace("}","");
                        ruleName=ruleName.replace(subTask.getId(),"");
                        //获取处理人
                        variables=getUserInfoByTaskIdAndRuleName(subTask.getId(),ruleName,variables,procInstId);

                        //多实例处理规则
                        if(subTask.getBehavior() instanceof SequentialMultiInstanceBehavior){
                            SequentialMultiInstanceBehavior sequentialMultiInstanceBehavior=(SequentialMultiInstanceBehavior)subTask.getBehavior();
                            //获取多实例处理规则
                            String expressionText=sequentialMultiInstanceBehavior.getCollectionVariable();
                            expressionText=expressionText.replace(subTask.getId(),"");
                            variables=getUserInfoByTaskIdAndRuleName(subTask.getId(),expressionText,variables,procInstId);
                        }
                        //多实例处理规则，如果是 并行多重事件
                        if(subTask.getBehavior() instanceof ParallelMultiInstanceBehavior){
                            ParallelMultiInstanceBehavior parallelMultiInstanceBehavior=(ParallelMultiInstanceBehavior)subTask.getBehavior();
                            //获取多实例处理规则
                            String expressionText=parallelMultiInstanceBehavior.getCollectionVariable();
                            expressionText=expressionText.replace(subTask.getId(),"");
                            variables=getUserInfoByTaskIdAndRuleName(subTask.getId(),expressionText,variables,procInstId);
                        }
                    }
                }//报错说明这是普通流程的结束
                catch (Exception e) {
                    if(redisUtils.exists(procInstId+"_end")){
                        redisUtils.remove(procInstId+"_end");
                    }
                    redisUtils.set(procInstId+"_sms","流程已结束。");
                    return variables;
                }
            }
            //如果是子流程
            else if(targetFlowElement instanceof SubProcess){
                //获取子流程对象
                Collection<FlowElement> subProcess=((SubProcess) targetFlowElement).getFlowElements();
                for (FlowElement fl : subProcess) {
                    //判断是否是子流程开始节点
                    if (fl instanceof StartEvent) {
                        List<SequenceFlow> subOutgoingFlows =((StartEvent) fl).getOutgoingFlows();
                        //取子流程中开始节点后面的第一个usertask
                        UserTask subTask = (UserTask) subOutgoingFlows.get(0).getTargetFlowElement();
                        //获取处理人规则
                        String candidateUsers=subTask.getCandidateUsers().get(0);
                        String ruleName=candidateUsers.replace("$","");
                        ruleName=ruleName.replace("{","");
                        ruleName=ruleName.replace("}","");
                        ruleName=ruleName.replace(subTask.getId(),"");
                        //获取处理人
                        variables=getUserInfoByTaskIdAndRuleName(subTask.getId(),ruleName,variables,procInstId);
                        //多实例处理规则
                        if(subTask.getBehavior() instanceof SequentialMultiInstanceBehavior){
                            SequentialMultiInstanceBehavior sequentialMultiInstanceBehavior=(SequentialMultiInstanceBehavior)subTask.getBehavior();
                            //获取多实例处理规则
                            String expressionText=sequentialMultiInstanceBehavior.getCollectionVariable();
                            expressionText=expressionText.replace(subTask.getId(),"");
                            variables=getUserInfoByTaskIdAndRuleName(subTask.getId(),expressionText,variables,procInstId);
                        }
                        //多实例处理规则，如果是 并行多重事件
                        if(subTask.getBehavior() instanceof ParallelMultiInstanceBehavior){
                            ParallelMultiInstanceBehavior parallelMultiInstanceBehavior=(ParallelMultiInstanceBehavior)subTask.getBehavior();
                            //获取多实例处理规则
                            String expressionText=parallelMultiInstanceBehavior.getCollectionVariable();
                            expressionText=expressionText.replace(subTask.getId(),"");
                            variables=getUserInfoByTaskIdAndRuleName(subTask.getId(),expressionText,variables,procInstId);
                        }
                    }
                }
            }
            //如果是等待任务
            else if(targetFlowElement instanceof ReceiveTask){
                return variables;
            }
            //如果是调用任务
            else if(targetFlowElement instanceof CallActivity){
                // todo:1.调用子流程（数据同步、父流程进入下一步？父流程暂停？子流程结束后父流程进入下一步？）
                // todo:2.调用webapi
                // todo:3.调用sql
                CallActivity callActivity = (CallActivity) targetFlowElement;
                List<SequenceFlow> callActivityOutgoingFlows = callActivity.getOutgoingFlows();
                UserTask callActivityTask = (UserTask) callActivityOutgoingFlows.get(0).getTargetFlowElement();
                //获取处理人规则
                String candidateUsers=callActivityTask.getCandidateUsers().get(0);
                String ruleName=candidateUsers.replace("$","");
                ruleName=ruleName.replace("{","");
                ruleName=ruleName.replace("}","");
                ruleName=ruleName.replace(callActivityTask.getId(),"");
                //获取处理人
                variables=getUserInfoByTaskIdAndRuleName(callActivityTask.getId(),ruleName,variables,procInstId);
                //多实例处理规则
                if(callActivityTask.getBehavior() instanceof SequentialMultiInstanceBehavior){
                    SequentialMultiInstanceBehavior sequentialMultiInstanceBehavior=(SequentialMultiInstanceBehavior)callActivityTask.getBehavior();
                    //获取多实例处理规则
                    String expressionText=sequentialMultiInstanceBehavior.getCollectionVariable();
                    expressionText=expressionText.replace(callActivityTask.getId(),"");
                    variables=getUserInfoByTaskIdAndRuleName(callActivityTask.getId(),expressionText,variables,procInstId);
                }
                //多实例处理规则，如果是 并行多重事件
                if(callActivityTask.getBehavior() instanceof ParallelMultiInstanceBehavior){
                    ParallelMultiInstanceBehavior parallelMultiInstanceBehavior=(ParallelMultiInstanceBehavior)callActivityTask.getBehavior();
                    //获取多实例处理规则
                    String expressionText=parallelMultiInstanceBehavior.getCollectionVariable();
                    expressionText=expressionText.replace(callActivityTask.getId(),"");
                    variables=getUserInfoByTaskIdAndRuleName(callActivityTask.getId(),expressionText,variables,procInstId);
                }
            }
            else {
                UserTask defUserTask=(UserTask) targetFlowElement;
                //获取处理人规则
                String candidateUsers=defUserTask.getCandidateUsers().get(0);
                String ruleName=candidateUsers.replace("$","");
                ruleName=ruleName.replace("{","");
                ruleName=ruleName.replace("}","");
                ruleName=ruleName.replace(defUserTask.getId(),"");
                //获取处理人
                variables=getUserInfoByTaskIdAndRuleName(defUserTask.getId(),ruleName,variables,procInstId);
                //多实例处理规则
                if(defUserTask.getBehavior() instanceof SequentialMultiInstanceBehavior){
                    SequentialMultiInstanceBehavior sequentialMultiInstanceBehavior=(SequentialMultiInstanceBehavior)defUserTask.getBehavior();
                    //获取多实例处理规则
                    String expressionText=sequentialMultiInstanceBehavior.getCollectionVariable();
                    expressionText=expressionText.replace(defUserTask.getId(),"");
                    variables=getUserInfoByTaskIdAndRuleName(defUserTask.getId(),expressionText,variables,procInstId);
                }
                //多实例处理规则，如果是 并行多重事件
                if(defUserTask.getBehavior() instanceof ParallelMultiInstanceBehavior){
                    ParallelMultiInstanceBehavior parallelMultiInstanceBehavior=(ParallelMultiInstanceBehavior)defUserTask.getBehavior();
                    //获取多实例处理规则
                    String expressionText=parallelMultiInstanceBehavior.getCollectionVariable();
                    expressionText=expressionText.replace(defUserTask.getId(),"");
                    variables=getUserInfoByTaskIdAndRuleName(defUserTask.getId(),expressionText,variables,procInstId);
                }
            }
            //返回接收人
            return variables;
        }
        catch(Exception ex) {
            return variables;
        }
    }
    private HashMap<String,Object> getUserInfoByTaskIdAndRuleName(String taskid,String ruleName,HashMap<String,Object> variables,String procInstId){
        List<AssigneeUserEntity> assigneeUserEntityList = assigneeUserService
                .getAssigneeUserWithTaskKey(taskid, ruleName);
        String nextWorkEmp="";

        switch (ruleName){
            case "_byUser":
                nextWorkEmp="";
                for (AssigneeUserEntity ae : assigneeUserEntityList) {
                    nextWorkEmp = nextWorkEmp + ae.getUsername() + ",";
                }
                nextWorkEmp = nextWorkEmp.substring(0, nextWorkEmp.length() - 1);
                variables.put(taskid + "_byUser", nextWorkEmp);
                break;
            case "_byUserList":
                nextWorkEmp="";
                List<String> userList=new ArrayList<>();

                for (AssigneeUserEntity ae : assigneeUserEntityList) {
                    if(nextWorkEmp.contains(ae.getUsername()+"@"))
                        continue;
                    userList.add(ae.getUsername());
                    nextWorkEmp = nextWorkEmp + ae.getUsername() + "@";
                }
                variables.put(taskid + "_byUserList", userList);
                break;
            case "_byDept":
                nextWorkEmp="";
                for (AssigneeUserEntity ae : assigneeUserEntityList) {
                    List<UserEntity> userEntityList=userEntityMapper.getUserByDepartId(Integer.parseInt(ae.getUsername()));
                    for(UserEntity userEntity:userEntityList){
                        nextWorkEmp = nextWorkEmp + userEntity.getUsername() + ",";
                    }
                }
                nextWorkEmp = nextWorkEmp.substring(0, nextWorkEmp.length() - 1);
                variables.put(taskid + "_byDept", nextWorkEmp);
                break;
            case "_byDeptList":
                nextWorkEmp="";
                List<String> deptList=new ArrayList<>();
                for (AssigneeUserEntity ae : assigneeUserEntityList) {
                    List<UserEntity> userEntityList=userEntityMapper.getUserByDepartId(Integer.parseInt(ae.getUsername()));
                    for(UserEntity userEntity:userEntityList){
                        if(nextWorkEmp.contains(userEntity.getUsername()+"@"))
                            continue;
                        deptList.add(userEntity.getUsername());
                        nextWorkEmp = nextWorkEmp + userEntity.getUsername() + "@";
                    }
                }
                variables.put(taskid + "_byDeptList", deptList);
                break;
            case "_byRole":
                nextWorkEmp="";
                for (AssigneeUserEntity ae : assigneeUserEntityList) {
                    List<UserEntity> userEntityList=userEntityMapper.getUserByRoleId(ae.getUsername());
                    for(UserEntity userEntity:userEntityList){
                        nextWorkEmp = nextWorkEmp + userEntity.getUsername() + ",";
                    }
                }
                nextWorkEmp = nextWorkEmp.substring(0, nextWorkEmp.length() - 1);
                variables.put(taskid + "_byRole", nextWorkEmp);
                break;
            case "_byRoleList":
                nextWorkEmp="";
                List<String> roleList=new ArrayList<>();

                for (AssigneeUserEntity ae : assigneeUserEntityList) {
                    List<UserEntity> userEntityList=userEntityMapper.getUserByRoleId(ae.getUsername());
                    for(UserEntity userEntity:userEntityList){
                        if(nextWorkEmp.contains(userEntity.getUsername()+"@"))
                            continue;
                        roleList.add(userEntity.getUsername());
                        nextWorkEmp = nextWorkEmp + userEntity.getUsername() + "@";
                    }
                }
                variables.put(taskid + "_byRoleList", roleList);
                break;
            case "_byPosition":
                nextWorkEmp="";
                for (AssigneeUserEntity ae : assigneeUserEntityList) {
                    List<UserEntity> userEntityList=userEntityMapper.getUserByPositionId(ae.getUsername());
                    for(UserEntity userEntity:userEntityList){
                        nextWorkEmp = nextWorkEmp + userEntity.getUsername() + ",";
                    }
                }
                nextWorkEmp = nextWorkEmp.substring(0, nextWorkEmp.length() - 1);
                variables.put(taskid + "_byPosition", nextWorkEmp);
                break;
            case "_byPositionList":
                nextWorkEmp="";
                List<String> positonList=new ArrayList<>();
                for (AssigneeUserEntity ae : assigneeUserEntityList) {
                    List<UserEntity> userEntityList=userEntityMapper.getUserByPositionId(ae.getUsername());
                    for(UserEntity userEntity:userEntityList){
                        if(nextWorkEmp.contains(userEntity.getUsername()+"@"))
                            continue;
                        positonList.add(userEntity.getUsername());
                        nextWorkEmp = nextWorkEmp + userEntity.getUsername() + "@";
                    }
                }
                variables.put(taskid + "_byPositionList", positonList);
                break;
        }
        if(redisUtils.exists(procInstId+"_sms")){
            redisUtils.remove(procInstId+"_sms");
        }
        redisUtils.set(procInstId+"_sms",nextWorkEmp);
        return variables;
    }
    @Override
    public HashMap<String,Object> getTodoList(Integer pageNum,Integer pagesize,String flowName){
        //获取当前登录用户信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String username=authentication.getName();
        List<GenerWork> generWorkList=generWorkMapper.getTodoList(username,pageNum,pagesize,flowName);
        List<GenerWork> generWorkNum=generWorkMapper.getTodoListNum(username,flowName);
        HashMap<String,Object> hashMap=new HashMap<>();
        hashMap.put("list",generWorkList);
        hashMap.put("total",generWorkNum.size());
        return hashMap;
    }
    @Override
    public HashMap<String,Object> getTodoTask(String flowSort, String proceId, Integer page, Integer pagesize){
        Integer startIndex=0;
        Integer maxltems=0;
        if(page==1) {
            startIndex = 0;
            maxltems=pagesize;
        }
        else{
            startIndex=pagesize*(page-1);
            maxltems=page*page;
        }
        //获取当前登录用户信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String username=authentication.getName();
        securityUtil.logInAs(username);
        //获取分页数据
        Page<Task> tasks = taskRuntime.tasks(Pageable.of(startIndex, maxltems));
        //构建返回数据
        List<HashMap<String, Object>> listMap = new ArrayList<HashMap<String, Object>>();

        for (Task tk : tasks.getContent()) {
            //用户获取流程名称
            ProcessInstance processInstance = processRuntime.processInstance(tk.getProcessInstanceId());
            HashMap<String, Object> hashMap = new HashMap<>();
            hashMap.put("id", tk.getId());//taskid，类似workid
            hashMap.put("name", tk.getName());//任务节点名称
            hashMap.put("status", tk.getStatus());//任务状态
            hashMap.put("createdDate", tk.getCreatedDate());//任务创建时间，实际就是任务到达时间
            if (tk.getAssignee() == null) {//执行人，null时前台显示未拾取
                hashMap.put("assignee", "待拾取任务");
            } else {
                hashMap.put("assignee", tk.getAssignee());//执行人
            }
            hashMap.put("procinstid",tk.getProcessInstanceId());
            hashMap.put("instanceName", processInstance.getName());
            listMap.add(hashMap);
        }

        HashMap<String,Object> taskMap=new HashMap<>();
        taskMap.put("list",listMap);
        taskMap.put("total",listMap.size());

        return taskMap;
    }

    /**
     * 获取已办列表
     * @param
     * @param
     * @param
     * @param pagesize
     * @return
     */
    @Override
    public HashMap<String, Object> getHistoricTaskInstance(String flowName, Integer pageNum
            , Integer pagesize){
        Integer startIndex=0;
        Integer maxltems=0;
        if(pageNum==1) {
            startIndex = 0;
        }
        else{
            startIndex=pagesize*(pageNum-1);
        }
        //获取当前登录用户信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String username=authentication.getName();
        List<GenerWork> generWorkList=generWorkMapper.getDoneList(username,startIndex,pagesize,flowName);
        List<GenerWork> generWorkNum=generWorkMapper.getDoneListNum(username,flowName);
        HashMap<String,Object> hashMap=new HashMap<>();
        hashMap.put("list",generWorkList);
        hashMap.put("total",generWorkNum.size());
        return hashMap;
    }
    @Override
    public String saveForm(String proce_inst_id,String id){
        try{
            GenerWork generWork=new GenerWork();
            generWork.setId(id);
            generWork.setCreatetime(DateTime.now().toString("yyyy-MM-dd hh:mm:ss"));

            generWork.setProce_inst_id(proce_inst_id);

            generWorkMapper.updateFlowWork(generWork);
            return id;
        }
        catch (Exception ex){
            return ex.getMessage();
        }
    }
    public void setApprovalTrack(String Task_def_key,String Name,ProcessTaskParams processTaskParams,Integer actionType,String actionName){
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String username = authentication.getName();
        ApprovalTrack approvalTrack=new ApprovalTrack();
        approvalTrack.setUuid(UUID.randomUUID().toString());
        approvalTrack.setUserTaskId(Task_def_key);
        approvalTrack.setUserTaskName(Name);
        approvalTrack.setUser(username);
        approvalTrack.setProcess_ints_id(processTaskParams.getProcessInstanceId());
        approvalTrack.setActionType(actionType);
        approvalTrack.setActionName(actionName);
        approvalTrack.setMsg(processTaskParams.getMsg());
        approvalTrack.setMsgFiles(processTaskParams.getMsgFiles());
        approvalTrack.setFilePath(processTaskParams.getFilePath());
        approvalTrack.setRdt(DateUtils.getDate("yyyy-MM-dd HH:mm:ss"));
        approvalTrackMapper.addApprovalTrack(approvalTrack);
    }
}
